/**
 * react18版本和19版本使用获取子组件dom元素的区别
 * 执行时机和㱇:LayoutEffect的配置项一样 => 组件渲染完成会执行,不传入第三个参数
 * 也会执行,传入配置项(配置的哪个就依赖哪个)
 */
import React, { useRef, useImperativeHandle, useState } from "react"

interface ChildRef {
    name: string;
    name1: number;
    addNmae: () => void;
    subName: () => void;
    formData?: FormData;
    reset?: () => void;
    validate?: () => boolean | string;
}
// react18版本
const Child = React.forwardRef<ChildRef>((props, ref) => {
    const [name1, setName1] = useState(0)
    useImperativeHandle(ref, () => {
        return {
            name: 'child',
            name1,
            addNmae: () => setName1(name1 + 1),
            subName: () => setName1(name1 - 1)
        }
    })
    return <div>
        <h3 ref={ref}>子组件</h3>
        <div>name:{name1}</div>
        <button onClick={() => setName1(name1 + 1)}>增加</button>
        <button onClick={() => setName1(name1 - 1)}>减少</button>
    </div>
})
// react19版本
// const ChildClone = ({ref}:{ref:React.Ref<ChildRef>}) => {
//     const [name1, setName1] = useState(0)
//     useImperativeHandle(ref,() => {
//         return {
//             name:'childClone',
//             name1:100,
//             addNmae:() => setName1(name1 + 1),
//             subName:() => setName1(name1 -1)
//         }
//     })
//     return <div>
//         <h3>子组件</h3>
//         <div>name:{name1}</div>
//         <button onClick={() => setName1(name1 + 1)}>增加</button>
//         <button onClick={() => setName1(name1 - 1)}>减少</button>
//     </div>
// }

// 实践封装一个表单组件
interface FormData {
    name: string;
    age: string;
    email: string;

}
// Add this interface before the Form component
interface FormRef {
    formData: FormData;
    reset: () => void;
    validate: () => boolean | string;
}
// Update Form's forwardRef type
const Form = React.forwardRef<FormRef>((_, ref) => {
    // 校验方法
    const validate = (): boolean | string => {
        if(formData.name.length < 3){
            return '名字不能小于3个字符'
        }
        if(formData.age.length < 18){
            return '年龄不能小于18岁'
        }
        if(formData.email.length < 10){
            return '邮箱不能小于10个字符'
        }
        return '校验成功'; // Add your validation logic here
    }
    // 重置方法
    const reset = () => {
        setFormData({
            name: '',
            age: '',
            email: '',
        })
    }
    // 表单数据
    const [formData, setFormData] = useState<FormData>({
        name: '',
        age: '',
        email: '',
    })
    useImperativeHandle(ref,() => {
        return {
            formData,
            validate:validate,
            reset:reset
        }
    })
    return <div>
        <h3>表单组件</h3>
        <form>
            姓名: <input value={formData.name} onChange={(e) => setFormData({ ...formData, name: e.target.value })} type="text" />
            <br />
            年龄: <input value={formData.age} onChange={(e) => setFormData({ ...formData, age: e.target.value })} type="text" />
            <br />
            邮箱: <input value={formData.email} onChange={(e) => setFormData({ ...formData, email: e.target.value })} type="text" />
        </form>
    </div>
})
function UseImperativeHandleHook() {
    // react18版本左右 useRef不是必传项
    // react19版本左右 useRef是必传项
    const childRef = useRef<ChildRef>(null)
    const formRef = useRef<FormRef>(null)
    
    const getChildInfo = () => {
        console.log(childRef.current);
        // 通过useImperativeHandle向子组件透传的属性方法,这里都可以接受到
        console.log(childRef.current!.name);
    }
    return <div>
        <div>父组件</div>
        <hr />
        {/* react18版本左右 */}
        <Child ref={childRef} />
        <button onClick={getChildInfo}>获取子组件dom元素</button>
        <div>触发子组件的事件</div>
        <button onClick={() => childRef.current?.addNmae()}>操作子组件增加</button>
        <button onClick={() => childRef.current?.subName()}>操作子组件减少</button>
        {/* react19版本 */}
        {/* <ChildClone ref={childRef} />
        <button onClick={getChildInfo}>获取子组件dom元素</button>
        <div>触发子组件的事件</div>
        <button onClick={() => childRef.current?.addNmae()}>操作子组件增加</button>
        <button onClick={() => childRef.current?.subName()}>操作子组件减少</button> */}
        <Form ref={formRef} />
        <button onClick={() => formRef.current!.reset()}>重置</button>
        <button onClick={() => {
            const result = formRef.current!.validate!();
            console.log(result);
        }}>校验</button>
    </div>
}
export default UseImperativeHandleHook